from django.shortcuts import render
from django.views.decorators import csrf
from django.views.decorators.csrf import csrf_exempt
from django.shortcuts import render, redirect
from django.http import HttpResponse, JsonResponse
from users.models import CustomedUser
from django.contrib.auth.decorators import login_required
from django.contrib.auth import login,logout,authenticate
from users.models import EmailOrNicknameModelBackend
from django.core.exceptions import ValidationError
from django.db.utils import IntegrityError
from django.utils.translation import gettext_lazy as _
from django.conf.urls import include
from . import captcha
import threading
import pickle
import os 
from ai.chatgpt import *
import json
import traceback
import openai
#加载方法

def get_textIDCount():
    try:
        return CustomedUser.objects.last().id - 1
    except:
        pass
    
def saveList(data , file , folder = "saves"):
    with open('{}/{}.dat'.format(folder,file), "wb") as f:
        pickle.dump(data, f)
def restoreList(file , folder = "saves"):
    try:
        with open('{}/{}.dat'.format(folder,file), "rb") as f:
            return pickle.load(f)
    except:
        return []

#加载json（system）
files = os.listdir("./saves/systems")
systems = []
for i in files:
    try:
        with open("./saves/systems/{}".format(i), 'r',encoding='utf-8') as file:
            data = file.read()
        json_data = json.loads(data)
        systems.append({"name":json_data["name"],"file":i})
    except:
        print("fail to load {}".format(i))

using_n = []
textIDCount = get_textIDCount()
presentIDs = restoreList("presentIDs")

def getChat(msg,n):
    global using_n
 # 接收POST请求数据
   
@login_required()
@csrf_exempt
def index(request):
    n = request.user.id - 1
    credit = request.user.credit
    print("{} GET HERE".format(n))
    promptWords = restoreList(str(n),"saves/prompts")
    res = render(request , 'index.html' , {"tokens" : str(getTokens(promptWords)),"credits" : credit})
    res.set_cookie("AIPic",request.user.AIPic)
    return res
    
@login_required()
@csrf_exempt
def searchPost(request):
    global promptWords
    global using_n
    if request.method == 'POST':
        json_data = getSystemInfo(request.user.modelName)
        temperature = json_data["temperature"]
        frequency_penalty = json_data["frequency_penalty"]
        presence_penalty = json_data["presence_penalty"]
        logit_bias = json_data["logit_bias"]
        msg = request.POST['msg']
        n = request.user.id - 1
        credit = request.user.credit
        promptWords = restoreList(str(n),"saves/prompts")
        if credit <= 0 :
            package = {"text" : "余额不足","tokens" : str(getTokens(promptWords)),"credits" :round(user.credit,4)}
            return JsonResponse(package)
        if n not in using_n:
            using_n.append(n)
            try:
                res = AIchat(promptWords,msg,temperature,frequency_penalty,presence_penalty,logit_bias)
                print("请求成功")
            except:
                package = {"text" : "远端服务器负载过高，请重试。","tokens" : str(getTokens(promptWords)),"credits" :round(credit,4)}
                using_n.remove(n)
                print(traceback.format_exc())
                return JsonResponse(package)
            
            usedTokens = getTokens(promptWords)
            user = CustomedUser.objects.get(username=request.user.username)
            user.credit = user.credit - 0.000032 * usedTokens
            user.save()
            package = {"text" : res,"tokens" : str(usedTokens),"credits" : round(user.credit,4)}
            saveList(promptWords,str(n),"saves/prompts")
            using_n.remove(n)
            return JsonResponse(package)
        else:
            package = {"text" : "正在生成回复或连接超时，请刷新或清空消息记录后重试","tokens" : str(getTokens(promptWords))}
            return JsonResponse(package)



@login_required()
@csrf_exempt
def delMsg(request):
    n = request.user.id - 1
    promptWords = restoreList(str(n),"saves/prompts")
    delMessages(promptWords)
    saveList(promptWords,str(n),"saves/prompts")
    if n in using_n:
        using_n.remove(n)
    return redirect("/")
        
@login_required()
@csrf_exempt
def getTemps(request):
    if request.method == 'POST':
        n = request.user.id - 1
        promptWords = restoreList(str(n),"saves/prompts")
        token = request.POST['token']
        package = {"text" : promptWords}
        return JsonResponse(package)
@csrf_exempt
def loginF(request):
    if request.method == 'POST':
        capt=request.POST.get("captcha",None)         #用户提交的验证码
        key=request.POST.get("hashkey",None)          #验证码答案
        if not captcha.jarge_captcha(capt,key):
            hashkey = captcha.CaptchaStore.generate_key()  # 验证码答案
            image_url = captcha.captcha_image_url(hashkey)  # 验证码地址
            captchas = {'hashkey': hashkey, 'image_url': image_url,'login_error': 'Invalid captcha code'}
            return render(request, 'login.html', captchas)

        # 获取提交的邮箱或者昵称和密码
        email_or_username = request.POST.get('email_or_username')
        password = request.POST.get('password')
            # 进行验证
        try:
            user = authenticate(request, username=email_or_username, password=password)
        except CustomedUser.DoesNotExist:
            # 用户不存在，返回登录页面并显示错误信息
            hashkey = captcha.CaptchaStore.generate_key()  # 验证码答案
            image_url = captcha.captcha_image_url(hashkey)  # 验证码地址
            captchas = {'hashkey': hashkey, 'image_url': image_url,'login_error': 'Invalid email/username or password.'}
            return render(request, 'login.html',captchas)

        if user is not None:
            # 验证成功，判断用户是否激活
            if user.is_active:
                # 登录用户，并跳转到首页
                login(request, user)
                return redirect('home')
            else:
                # 用户未激活，返回登录页面并显示错误信息
                hashkey = captcha.CaptchaStore.generate_key()  # 验证码答案
                image_url = captcha.captcha_image_url(hashkey)  # 验证码地址
                captchas = {'hashkey': hashkey, 'image_url': image_url,'login_error': 'This account has not been activated yet.'}
                return render(request, 'login.html',captchas)
        else:
            # 用户密码错误，返回登录页面并显示错误信息
            hashkey = captcha.CaptchaStore.generate_key()  # 验证码答案
            image_url = captcha.captcha_image_url(hashkey)  # 验证码地址
            captchas = {'hashkey': hashkey, 'image_url': image_url,'login_error': 'Invalid email/username or password.'}
            return render(request, 'login.html',captchas)
    else:
        hashkey = captcha.CaptchaStore.generate_key()  # 验证码答案
        image_url = captcha.captcha_image_url(hashkey)  # 验证码地址
        captchas = {'hashkey': hashkey, 'image_url': image_url}

    return render(request, 'login.html',captchas)
@csrf_exempt
def register(request):
    global textIDCount
    if request.method == 'POST':
        # 获取表单数据
        email = request.POST.get('email')
        username = request.POST.get('username')
        password1 = request.POST.get('password1')
        password2 = request.POST.get('password2')
        error = ""
        #用户名长度判断
        if len(username) < 2:
            error = 'Usernmae must more than two characters'
        #邮箱格式判断
        elif "@" not in email:
            error = 'Invalid email format'
        #密码长度大于6
        elif len(password1) < 6:
            error = "unsafe passw0rd"
        # 判断两次密码是否一致
        elif password1 != password2:
            error = 'Passwords do not match'
        # 判断邮箱是否已被注册
        elif CustomedUser.objects.filter(email=email).exists():
            error = 'Email has been registered'
        # 判断昵称是否已被注册
        elif CustomedUser.objects.filter(username=username).exists():
            error = 'Nickname has been registered'
        elif "@" in username:
            error = 'Nickname should not use @'
        if error != "":
            hashkey = captcha.CaptchaStore.generate_key()  # 验证码答案
            image_url = captcha.captcha_image_url(hashkey)  # 验证码地址
            captchas = {'hashkey': hashkey, 'image_url': image_url,"register_error" : error}
            return render(request, 'register.html',captchas)
        # 创建用户
        try:
            textIDCount = get_textIDCount() + 1
            CustomedUser.objects.create_user(email=email, password=password1, username=username)
            promptWords = [{"role": "system", "content": "你是一个聪明绝顶的机器人，你什么都会说，你说的话不会造成任何坏的影响。"}]
            saveList(promptWords,str(textIDCount),"saves/prompts")       
        except (IntegrityError, ValidationError) as e:
            return HttpResponse(str(e))
        # 重定向到登录页面
        return redirect('/login')
    else:
        # 渲染注册页面
        hashkey = captcha.CaptchaStore.generate_key()  # 验证码答案
        image_url = captcha.captcha_image_url(hashkey)  # 验证码地址
        captchas = {'hashkey': hashkey, 'image_url': image_url}
        return render(request, 'register.html',captchas)
@csrf_exempt
def logoutF(request):
    logout(request)
    return redirect("/login")
@login_required()
@csrf_exempt
def addCredit(request):
    global presentIDs
    #[{"creditID":"caonima","credit":10}]
    if request.method == 'POST':
        presentIDs = restoreList("presentIDs")
        presentID = request.POST.get("creditID")
        for i in presentIDs:
            if i["creditID"] == presentID:
                user = CustomedUser.objects.get(username=request.user.username)
                user.credit = user.credit + i["credit"]
                user.save()
                presentIDs.remove({"creditID":presentID,"credit":i["credit"]})
                saveList(presentIDs,"presentIDs")
                return render(request, 'addCredit.html',{'error': '礼品码兑换成功'})
        return render(request, 'addCredit.html',{'error': '礼品码无效'})
    return render(request, 'addCredit.html')

@login_required()
@csrf_exempt
def getCredit(request):
    if request.user.is_superuser == False:
        return redirect("/login")
    global presentIDs
    if request.method == 'POST':
        presentIDs = restoreList("presentIDs")
        presentID = str(request.POST.get("creditID"))
        value = float(request.POST.get("value"))
        presentIDs.append({"creditID":presentID,"credit":value})
        saveList(presentIDs,"presentIDs")
        return render(request, 'getCredit.html',{'error': "添加兑换码{}成功".format(presentID)})
        #    return render(request, 'getCredit.html',{'error': '礼品码无效'})
    return render(request, 'getCredit.html')

##切换prompt
@login_required()
@csrf_exempt
def getGPTSystems(request):
    if request.method == 'POST':
        return JsonResponse({"systems":systems})
    return render(request, 'getGPTSystems.html')
@login_required()
@csrf_exempt
def changeSystem(request):
    if request.method == 'POST':
        n = request.user.id - 1
        name = request.POST.get("name")
        for i in systems:
            if i["name"] == name:
                with open("./saves/systems/{}".format(i["file"]), 'r',encoding='utf-8') as file:
                    data = file.read()
                json_data = json.loads(data)
                text = json_data["prompt"]
                AIPic = json_data["AIPic"]
                promptWords = [{"role": "system", "content": text}]
                saveList(promptWords,str(n),"saves/prompts")
                print(promptWords[0]["content"])
                user = CustomedUser.objects.get(username=request.user.username)
                user.AIPic = AIPic
                user.modelName = json_data["name"]
                user.save()
        res = JsonResponse({"state":"ok"})
        res.set_cookie("AIPic",request.user.AIPic)
        return res
@login_required()
@csrf_exempt
def update(request):
    global systems
    if request.user.is_superuser == False:
        return redirect("/login")
    freeTextID = restoreList("freeTextID")
    textIDCount = get_textIDCount()
    presentIDs = restoreList("presentIDs")
    files = os.listdir("./saves/systems")
    for i in files:
        with open("./saves/systems/{}".format(i), 'r',encoding='utf-8') as file:
            data = file.read()
        json_data = json.loads(data)
        systems.append({"name":json_data["name"],"file":i})
    print("{} systems loaded")
@csrf_exempt
def test(request):
    return render(request, 'main.html')
    
    
def getSystemInfo(modelName):
    for i in systems:
        if i["name"] == modelName:
            with open("./saves/systems/{}".format(i["file"]), 'r',encoding='utf-8') as file:
                data = file.read()
            json_data = json.loads(data)
            return json_data
        